using System;
using System.Reflection;
using T.FAS.Runtime.Metadata.Entity;
using T.FAS.Runtime.Action.Engine;
using T.FAS.Runtime.Action.SPI;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;

namespace T.FAS.Runtime.Action.Engine
{
    class ActionRunTimeEngineFactory
    {
        public static IActionExecuteProxy Create(ActionRunTimeEngineConfig config = null)
        {
            IActionExecuteProxy engine = null;
            if (config == null)
            {
                engine = new SGActionEngine();
                return engine;
            }
            var assembly = Assembly.Load(config.ImplementAssembly);
            var instance = assembly.CreateInstance(config.ImplementType, true);
            if (instance != null)
            {
                if (instance is IActionExecuteProxy)
                    engine = instance as IActionExecuteProxy;
                else
                {
                    throw new FasException(ActionExecuteExceptionCode.LoadActionExecuteEngineError, CommonStringClassEngine.ActionRunTimeEngineFactory_Create+ instance.GetType().FullName);
                }
            }
            return engine;
        }

        public static IActionExecuteProxy Create(SPI.ActionExecContext context)
        {
            IActionExecuteProxy engine = null;
            if (context == null)
            {
                engine = new SGActionEngine();
                return engine;
            }
            if (context.ActionPlugin == null)
            {
                if (context.ActionType == SPI.ActionType.DQ)
                {
                    var dataquery = context.MetaData as DataQuery;
                    engine = new DQActionEngine();
                }
                else if (context.ActionType == SPI.ActionType.Action)
                {
                    if (string.IsNullOrEmpty(context.MetadataID))
                    {
                        engine = new SGActionEngine();
                        return engine;
                    }
                    var action = ActionRTPUtil.ActionMetadataValid(context.MetaData);
                    context.MetaData = action;
                    //客户端action
                    if (!action.IsClientAction)
                    {
                        switch (action.ActionType)
                        {
                            case Metadata.Entity.ActionType.SG:
                                engine = new SGActionEngine();
                                break;
                            case Metadata.Entity.ActionType.WebAPI:
                                engine = new WebAPIActionEngine();
                                break;
                            case Metadata.Entity.ActionType.CDO:
                                engine = new CDOActionEngine();
                                break;
                            case Metadata.Entity.ActionType.DQ:
                                engine = new DQActionEngine();
                                break;
                            case Metadata.Entity.ActionType.JSScript:
                                engine = new ServerJSActionEngine();
                                break;
                            case Metadata.Entity.ActionType.SQL:
                                engine = new SQLActionEngine();
                                break;
                            default:
                                engine = default;
                                break;
                        }
                    }
                }
                else if (context.ActionType == SPI.ActionType.CDO_ChangeState
                    || context.ActionType == SPI.ActionType.CDO_NewInstance
                    || context.ActionType == SPI.ActionType.CDO_FireEvent
                    || context.ActionType == SPI.ActionType.CDO_FireEventWithRecord
                    )
                {
                    engine = new CDOActionEngine();
                }
                else if (context.ActionType == SPI.ActionType.CDO_BatchUpdate || context.ActionType == SPI.ActionType.CDO_BatchDelete
                    || context.ActionType == SPI.ActionType.CDO_BatchCreate|| context.ActionType == SPI.ActionType.CDO_BatchEditUpdate)
                {
                    engine = new CDOBatchActionEngine();
                }
                return engine;
            }
            else
            {
                Type o = Type.GetType(context.ActionPlugin.TargetAssembly);
                engine = Activator.CreateInstance(o, true) as IActionExecuteProxy;
                return engine;
            }
        }
    }
}
